package com.yehebl.orm.data.connection;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.jdbc.support.GeneratedKeyHolder;

import com.yehebl.orm.data.common.IJdbc;
import com.yehebl.orm.data.common.IResultSet;
import com.yehebl.orm.exception.ConnectionException;

/**
 * 本地jdbc 实现
 */
public class LocalJdbc implements IJdbc {
	
	private final DataSource dataSource;
	public LocalJdbc(DataSource dataSource) {
		this.dataSource=dataSource;
	}

	@Override
	public int update(String sql, Object... objs) throws SQLException {
		Connection connection = dataSource.getConnection();
		PreparedStatement ss = connection.prepareStatement(sql);
		if(objs!=null) {
			for (int i = 0; i < objs.length; i++) {
				ss.setObject(i+1, objs[i]);
			}
		}
		int result=ss.executeUpdate();
		ss.close();
		connection.close();
		return result;
	}

	@Override
	public int insert(String sql, GeneratedKeyHolder gk, Object... objs) throws SQLException {
		Connection connection = dataSource.getConnection();
		PreparedStatement ss = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
		if(objs!=null) {
			for (int i = 0; i < objs.length; i++) {
				ss.setObject(i+1, objs[i]);
			}
		}
		int result=ss.executeUpdate();   
        // 检索由于执行此 Statement 对象而创建的所有自动生成的键   
        ResultSet rs = ss.getGeneratedKeys();   
        if (rs.next()) {  
        	Map<String, Object> map=new HashMap<>();
        	map.put("GENERATED_KEY",rs.getObject(1));
        	gk.getKeyList().add(map);
        }  
		return result;
	}

	@Override
	public int update(String sql) throws SQLException {
		Connection connection = dataSource.getConnection();
		Statement ss = connection.createStatement();
		int result=ss.executeUpdate(sql);
		ss.close();
		connection.close();
		return result;
	}

	@Override
	public int[] batchUpdate(String sql, Object[]... objs) throws SQLException {
		Connection connection = dataSource.getConnection();
		PreparedStatement ss = connection.prepareStatement(sql);
		if(objs!=null) {
			for (Object[] obj : objs) {
				for (int j = 0; j < obj.length; j++) {
					ss.setObject(j + 1, obj[j]);
				}
				ss.addBatch();
			}
		}
		int [] result=ss.executeBatch();
		ss.close();
		connection.close();
		return result;
	}

	@Override
	public <T> T query(String sql, IResultSet<T> resultSet, Object... objs) throws Exception {
		Connection connection = dataSource.getConnection();
		PreparedStatement ss = connection.prepareStatement(sql);
		if(objs!=null) {
			for (int i = 0; i < objs.length; i++) {
				ss.setObject(i+1, objs[i]);
			}
		}
		ResultSet rs = ss.executeQuery();
		T result = resultSet.result(rs);
		rs.close();
		ss.close();
		connection.close();
		return result;
	}

	@Override
	public <T> T query(String sql, IResultSet<T> resultSet) throws Exception {
		Connection connection = dataSource.getConnection();
		Statement ss = connection.createStatement();
		ResultSet rs = ss.executeQuery(sql);
		T result = resultSet.result(rs);
		rs.close();
		ss.close();
		connection.close();
		return result;
	}

	@Override
	public void execute(String sql) throws Exception {
		Connection connection = dataSource.getConnection();
		Statement ss = connection.createStatement();
		ss.execute(sql);
		ss.close();
		connection.close();
	}

	@Override
	public Connection getConnection() {
		try {
			return dataSource.getConnection();
		} catch (SQLException e) {
			throw new ConnectionException(e);
		}
	}

}
